/*
 * 1�����Ͳ�ѯָ��õ��豸������Ϣ
 * 2�������豸������Ϣ����ÿһ���豸
 */

/* * �޸���־ -------------------------------------------------------------------------------------------------------------------------------
 * date             ��        2020/10/30
 * author           :     huimin.li
 * content          :
 *                        1��������IAP����(flash.h��flash.c),����FLASH�Ļ��ֲο�flash.h��
 *                        2���޸����ж���������ӳ�� ,��0x8000000�޸�Ϊ 0x8004000�������޸���system_stm32f1xx.c�е�101��
 *                        3���޸��˳�������ӽű�link.lds�е�ROM��ʼ��ַ(��0x8000000�޸�Ϊ 0x8004000)�ʹ�С(��64K�޸�Ϊ48K)
 *                        4���޸���static void WQ_StateQuery_FromWifi(rt_uint8_t *p, rt_uint32_t len)�����е�1175�к�1203��,�ϱ����豸������,
 *                        ������豸�ղ������ط�������������
 *                        5��������DEBUG_INFO�������Ƶ�����Ϣ��48��
 *                        6���޸���static void WQ_StateQuery_FromWifi(rt_uint8_t *p, rt_uint32_t len)������1182-1199�У��ϱ����豸�������汾
 *                        ��Ϣ�������APP�����ɹ�������ͼ��һֱ���е����⡣
 *
 * * -------------------------------------------------------------------------------------------------------------------------------------- */
/**
  * �ṹ������
 *
 *
 */
#include <rtthread.h>
#include <stdint.h>
#include "main.h"
#include "Timer_APP.h"
#include "ntc_table.h"
#include "water_quality.h" 
#include "flash.h"

#define DBG_TAG "WQ"
#define DBG_LVL DBG_LOG
#include <rtdbg.h>

/********* ����ʵ�������������ֵ***********/
#define ORIG_TDS_WARNING    		260
#define PURE_TDS_WARNING  		300
#define CONTINUE_WATER_TIME   	120
#define ONE_SEC_NOWATER_SCOPE   	5




/********* TOC ����***********/

static rt_uint8_t WQReadQuality[] = {0x02,0x04,0x00,0x64,0x00,0x08,0xB0,0x20};     //��׼ˮ�ʲ���

//const static rt_uint8_t WQCalibration[] = {0x02,0x10,0x00,0xF0,0x00,0x02,0x04,0xAD,0xA0,0x00,0x02,0x52,0xE0};
const static rt_uint8_t WQDevid[] = {0x02,0x2B,0x0E,0x04,0x00,0x37,0x27}; //��ȡ�豸ʶ��
const static rt_uint8_t WQAdjust[] = {0x02,0x06,0x00,0xF0,0xAD,0xA0,0xF5,0x22}; //�豸У׼
//const static rt_uint8_t WQDevid[] = {0x02,0x2B,0x00,0x00,0xF0,0xAD,0xA0}; //��ȡ�豸ʶ��

static struct rt_thread TocMeasure_Thread;
static rt_uint8_t TocMeasure_thread_stack[512];
#define TOC_THREAD_PRIORITY 20
#define TOC_THREAD_TICK 20

#define MQ_WQ_BUFF_LEN 768

/*
struct rt_messagequeue MQ_ToWQuaThread;
static rt_uint8_t MQpool_ToWQuaThread[MQ_WQ_BUFF_LEN];
*/

static struct rt_event WTocEvent;

extern rt_uint8_t * WTOC_GetDate(rt_uint16_t * len);
extern rt_err_t WTOC_SendDate(rt_uint8_t *pData, rt_uint16_t Size);


/******ˮ������*******/
#define WTT_TEMP_DISCON                     882    //����ǰ�����ݼ��ݣ�882��Ϊ��û������
#define TOC_ON_MEASURE						1
#define TOC_NOT_MEASURE					0

typedef struct{
  rt_uint32_t Pulse_Counter2;  	
  rt_uint32_t Pulse_Counter1_local;  //������¼���壬�����㣬
  rt_uint32_t water_count_last;                         //��һ�ε�����
  rt_uint32_t localVolumn;  		//������������λL
  rt_int32_t start_water_count;                 //�뿪ʼʱ������
  rt_int32_t three_second_water_count;                   //������������
  rt_uint32_t water_speed_max;                          //�������
  rt_uint32_t water_speed_current;                      //��ǰ����
  rt_uint32_t onMeasure;
  rt_uint32_t flowTime;

}WATER_FLOW_INFO;

static struct rt_timer WVL_timer_water_speed;                                //���ٶ�ʱ���߳̿��ƿ�
static rt_uint32_t water_speedTimeOut;                                  //�������ټ�ʱ��־
WATER_FLOW_INFO waterFlowInfo;

/******other ����*******/


#define STATE_OK			0
#define STATE_ERRO			1
#define ORIG_TDS_ALERT  	2
#define PURE_TDS_ALERT 	3
#define NO_WATER_FLOW  	4
#define WATER_LEAKAGE		5



water_equip_state mwqState;
water_equip_state mwqLastState;
rt_uint16_t faultAlertReport = REPORT_OK;

extern 	rt_int32_t waterInterVolumn;
rt_int32_t adjustVolum;


wq_info wqinfo;
water_temp_tds_info wttInfo;
/*
void WQ_SendMessage(rt_int32_t type)
{
    struct Msg_ToMain msg;
    rt_err_t result = RT_EOK;

    msg.dev = NULL;
    msg.size = 0;
    msg.MsgType = type;

	result = rt_mq_send(&MQ_ToWQuaThread, &msg, sizeof(msg));
    if (result == -RT_EFULL)
	{
		LOG_I("message MQ_ToWifiThread full\n");
	}
}
*/
extern uint16_t ADC_Read(uint32_t Channel);
void WTT_TdsTempMeasure(void)
{
    uint32_t ad0, ad1, ad4, ad5, ad6;
    int i;
    float temper;
    float sigleTD;
    float pipeTD;
    float res_val = 0.0;
    rt_err_t result = RT_EOK;

    if (result == RT_EOK)
    {
        ad0 = ADC_Read(ADC_CHANNEL_0);
        ad1 = ADC_Read(ADC_CHANNEL_1);
        ad4 = ADC_Read(ADC_CHANNEL_4);
		ad5 = ADC_Read(ADC_CHANNEL_5);
		ad6 = ADC_Read(ADC_CHANNEL_6);
		LOG_D("ad0=%d\n", (uint32_t)(ad0));
		LOG_D("ad1=%d\n", (uint32_t)(ad1));
		LOG_D("ad4=%d\n", (uint32_t)(ad4));
		LOG_D("ad5=%d\n", (uint32_t)(ad5));
		LOG_D("ad6=%d\n", (uint32_t)(ad6));
        temper = (float)(ad0  * 1.0) / 4096 * 3.3;
        sigleTD = (float)(ad4 * 1.0) / 4096 * 3.3;
        pipeTD = (float)(ad1  * 1.0) / 4096 * 3.3;
        LOG_D("temper=%d\n", (uint32_t)(temper));
        // LOG_D("adcValue=%d\n", (uint32_t)(adv * 100));
        wttInfo.origTds = (uint32_t)(pipeTD * 100);
        wttInfo.pureTds = (uint32_t)(sigleTD * 100);
        res_val = (10 * temper / (3.3 - temper));
        LOG_D("res_val=%d\n", (uint32_t)(res_val));
        wttInfo.waterTemperature = WTT_TEMP_DISCON;
        for (i = 1; i < sizeof(NTC_RES_TEMP_TABLE) / sizeof(NTC_RES_TEMP_TABLE[0]); i++)
        {
            if (res_val >= NTC_RES_TEMP_TABLE[i].res && res_val < NTC_RES_TEMP_TABLE[i - 1].res)
            {
                wttInfo.waterTemperature = NTC_RES_TEMP_TABLE[i - 1].temp;
                LOG_D("wttInfo.waterTemperature:%d\n", wttInfo.waterTemperature);
                break;
            }
        }

      	if(wttInfo.pureTds < PURE_TDS_WARNING) // ��ˮˮ�ʱ�����ֵ
      	{
			mwqState.tdsAlert = PURE_TDS_ALERT;

		}
	    else
	    {

	      	if(wttInfo.origTds < ORIG_TDS_WARNING) // ��ˮˮ�ʱ�����ֵ
	      	{
				mwqState.tdsAlert = ORIG_TDS_ALERT;
			}
		    else
		    {
				mwqState.tdsAlert = STATE_OK;
			}
		}
    }
}

void WTT_SelfCheck(void)
{
	WTT_TdsTempMeasure();
	if(wttInfo.waterTemperature == WTT_TEMP_DISCON) 
	{
		mwqState.wttDevState =STATE_ERRO;
//		LOG_I("WTT_SelfCheck erro");
	}
	else
		mwqState.wttDevState = STATE_OK;
}



void WVV_Ctrl(int num, int action) //����ˮ��
{
    GPIO_PinState state;

           LOG_I("valve start %d, %d\n",num,action);

    if (action == VALVE_ON)
        state = GPIO_PIN_SET;
    else
        state = GPIO_PIN_RESET ;
        
    switch (num)
        {
        case VALVE_OUT_DEV:
            HAL_GPIO_WritePin(VALUE1_GPIO_Port, VALUE1_Pin, state);
            break;
        case VALVE_IN_DEV:
            HAL_GPIO_WritePin(VALUE2_GPIO_Port, VALUE2_Pin, state);
            break;
        default:
            break;
        }
}


/****************************************************************************
begin of ˮ����غ���
****************************************************************************/

void WVL_VolumCount(uint16_t GPIO_Pin)
{
	static rt_int32_t count = 0;
	if (GPIO_Pin == TRG1_Pin) // ˮ������
	{
		LOG_I("trg1\n");
		waterFlowInfo.Pulse_Counter2 ++;	 
		waterFlowInfo.Pulse_Counter1_local ++;	 
		
		LedAct(LED_WATER_FLOW,LED_OFF,300,1);  //��2��

		count++;
		if(count >= PULSE_ONE_L)
		{
			count = 0;
			waterFlowInfo.localVolumn ++;	 

		}
		mwqState.waterFlowState = STATE_OK;

	}
	else if(GPIO_Pin == TRG2_Pin)
	{
	    LOG_I("trg2\n");
	}
}

static void WVL_dev_init(void)
{

   	FLASH_Read_Msg();

	
   /*��ʼ��ˮ������*/
   waterFlowInfo.water_count_last=0;
   waterFlowInfo.water_speed_current=0;
   waterFlowInfo.water_speed_max=0;
   waterFlowInfo.localVolumn =flashmsg.waterVolum;
   waterFlowInfo.Pulse_Counter2 = 0;
   waterFlowInfo.Pulse_Counter1_local = 0;
   waterFlowInfo.flowTime = 0;

	mwqState.tdsAlert = STATE_OK;
	mwqState.tocAlert = STATE_OK;
	mwqState.tocDevState = STATE_OK;
	mwqState.wttDevState = STATE_OK;
	mwqState.waterFlowState = STATE_OK;

	mwqLastState.tdsAlert = STATE_OK;
	mwqLastState.tocAlert = STATE_OK;
	mwqLastState.tocDevState = STATE_OK;
	mwqLastState.wttDevState = STATE_OK;
	mwqLastState.waterFlowState = STATE_OK;

	

	
}



static void WVL_waterSpeedTimer(void *parameter) //ÿ�����һ��
{ 
	rt_int32_t temp;                        

	if((waterFlowInfo.Pulse_Counter1_local - waterFlowInfo.water_count_last ) >= ONE_SEC_NOWATER_SCOPE)
	{ //����ˮ
		needMeasure = 0;
		waterFlowInfo.flowTime++;
		if(waterFlowInfo.flowTime >100000)
		{
			waterFlowInfo.flowTime = CONTINUE_WATER_TIME;
		}
	}
	else
	{// û����ˮ
		if(waterFlowInfo.flowTime > 1)//ˮ��ʱ�����2��,��������û����ˮ
		{
			needMeasure = 1;
		}
		if(needMeasure >0)
		{
			needMeasure ++;
		}

		waterFlowInfo.flowTime = 0; //û��ˮ��
		mwqState.waterLeakageState = STATE_OK;
	}
	waterFlowInfo.water_count_last = waterFlowInfo.Pulse_Counter1_local;

	if(	waterFlowInfo.flowTime >= CONTINUE_WATER_TIME) //����120����ˮ���������豸©ˮ
	{
		mwqState.waterLeakageState = WATER_LEAKAGE;
	}	


	


	if(	waterFlowInfo.onMeasure == TOC_ON_MEASURE)
	{
		water_speedTimeOut = 0;
		return;
	}

	if(water_speedTimeOut == 0)
	{	  
		waterFlowInfo.start_water_count=waterFlowInfo.Pulse_Counter1_local;    // //3���ӵ�����
	}

	water_speedTimeOut++;	

	if(water_speedTimeOut>3)
	{	
		water_speedTimeOut=0;
		
		waterFlowInfo.three_second_water_count=waterFlowInfo.Pulse_Counter1_local;		   

		// ÿ���ӵ�������
		temp=60*(waterFlowInfo.three_second_water_count-waterFlowInfo.start_water_count)/3; 
		// û���ӵĺ������� ml/min
		//����
		if(temp>=0)
		{
		     waterFlowInfo.water_speed_current=temp;						
		}	  
		/*ȡ�������*/
		if(waterFlowInfo.water_speed_current>waterFlowInfo.water_speed_max)
		{
		    waterFlowInfo.water_speed_max=waterFlowInfo.water_speed_current;
		}
	}	 
	 
}

int WVL_init(void)
{
   WVL_dev_init();
				
				  
   /*�������ٶ�ʱ���߳�*/
   rt_timer_init(&WVL_timer_water_speed,
				 "WVL_timer_water_speed",
				  WVL_waterSpeedTimer,
				  0,
				  1*RT_TICK_PER_SECOND,                               //��ʱ����1000��ϵͳʱ��(1����)
				  RT_TIMER_FLAG_PERIODIC);				              //��ʱ�����ڼ�ʱ
       rt_timer_start(&WVL_timer_water_speed);                            //������ʱ��
   return RT_EOK;

}

void WVL_clearMaxFlow(void)
{

	waterFlowInfo.water_speed_max = 0;

	return ;

}

rt_int32_t WVL_getMaxFlow(void)
{
	rt_int32_t result;

	result = waterFlowInfo.water_speed_max;

	return result;

}


void WVL_ClearWaterIntervalVolum(void)
{
	
	waterFlowInfo.Pulse_Counter2 = waterFlowInfo.Pulse_Counter2 -waterInterVolumn;
	waterInterVolumn =0;

	return;

}


rt_int32_t WVL_getWaterIntervalVolum(void)
{
	rt_int32_t result;

	result = waterFlowInfo.Pulse_Counter2;

	return result;

}

rt_int32_t WVL_getWaterLocalVolum(void)
{
		return waterFlowInfo.localVolumn;
}

/****************************************************************************
end of ˮ������
****************************************************************************/






void TOC_Action(rt_uint8_t FLAG)
{
/*    struct Msg_ToMain msg;
    rt_err_t result = RT_EOK;

    msg.dev = NULL;
    msg.size = 0;
    msg.MsgType = FLAG;

	result = rt_mq_send(&MQ_ToWQuaThread, &msg, sizeof(msg));
    if (result == -RT_EFULL)
	{
		LOG_I("message MQ_ToWifiThread full\n");
	}

*/
  //      LOG_D("wq event\n");
        rt_event_send(&WTocEvent, FLAG);

}


rt_err_t TOC_GetValue(void)
{
	wq_info wqRecord;
	rt_uint16_t len;  
	uint8_t testCount = 3;
    rt_err_t result = RT_EOK;
    uint8_t *p = NULL;

	wqRecord.res_toc=0;
	wqRecord.res_ntu=0;

	for(int i =0;i<testCount;i++) //����3��ȡƽ��ֵ����ʱ10��
	{
        result = WTOC_SendDate(WQReadQuality, sizeof(WQReadQuality));
        if (result == RT_EOK)
        {
            p = WTOC_GetDate(&len);
            LOG_D("get toc data, len = %d\n",len);

            wqinfo.res_valid = (*p << 8) | *(p + 1);
            wqinfo.res_score = *(p + 2) << 8 | *(p + 3);
            wqinfo.res_toc = *(p + 4) << 8 | *(p + 5);
            wqinfo.res_ntu = *(p + 6) << 8 | *(p + 7);
            wqinfo.res_pt100 = *(p + 8) << 8 | *(p + 9);
            wqinfo.res_tc = *(p + 10) << 8 | *(p + 11);
  //          wqinfo.res_cod = *(p + 12) << 8 | *(p + 13);
            rt_kprintf("res_valid:%d,res_score:%d,res_toc:%d,res_ntu:%d\n\res_pt100:%d,res_tc:%d\n",
                  wqinfo.res_valid,
                  wqinfo.res_score,
                  wqinfo.res_toc,
                  wqinfo.res_ntu,
                  wqinfo.res_pt100,
                  wqinfo.res_tc);
                  
			wqRecord.res_toc += wqinfo.res_toc;
			wqRecord.res_ntu += wqinfo.res_ntu;

        }
        else
        {
            rt_kprintf("get TOC result erro:%d\n", result);
        }
        rt_thread_mdelay(3000); 

    }

	wqinfo.res_toc = wqRecord.res_toc / 3;
	wqinfo.res_ntu = wqRecord.res_ntu/ 3;
  	wqinfo.res_cod = (rt_uint16_t)wqinfo.res_toc *10/ 13;

  	if(wqinfo.res_toc >80)
  	{
  		mwqState.tocAlert = STATE_ERRO;
	}
    else
    {
  		mwqState.tocAlert = STATE_OK;
	}

	return result;

}

rt_err_t TOC_Adjust(void)
{
    rt_err_t result = RT_EOK;
    rt_uint32_t waterVolumn1,waterVolumn2;


	if( mwqState.wttDevState != STATE_OK)
	{
        LOG_D("wttDevState erro\n");
		return RT_ERROR;
	}

    if(waterFlowInfo.flowTime != 0) //�û�����ˮ������ˮ����������ˮ�ʼ��У����ʺ�У׼
    {
        LOG_D("water is used erro\n");
		return RT_ERROR;
    }

	adjustVolum = WVL_getWaterLocalVolum();//���λ�ò�Ҫ˳�㻻��

	
	if(mwqState.tocDevState != STATE_OK)
	{
		LOG_D("tocDevState erro\n");
		return RT_ERROR;
	}

    if(mwqState.tdsAlert == PURE_TDS_ALERT)
    {
        LOG_D("pure water is pollution, erro\n");
		return RT_ERROR;
    }

	LedAct(LED_TOC_MEASURE,LED_ON,0,0); // 5 sec

	waterVolumn1 = waterFlowInfo.Pulse_Counter1_local;
    WVV_Ctrl(VALVE_OUT_DEV,VALVE_ON);
    rt_thread_mdelay(5000); //ˮ���򿪣��Ŵ���ˮˮ5����
    WVV_Ctrl(VALVE_OUT_DEV,VALVE_OFF);
    rt_thread_mdelay(2000); //ˮ���رգ��ȶ�2����

	LedAct(LED_TOC_MEASURE,LED_OFF,0,0); // 5 sec

	waterVolumn2 = waterFlowInfo.Pulse_Counter1_local;
	if((waterVolumn2 - waterVolumn1)<ONE_SEC_NOWATER_SCOPE*5)  //��ˮ����û��ˮ����
	{
		LedAct(LED_DEV_FAULT,LED_OFF,7000,1); // 7��
		LedAct(LED_WATER_FLOW,LED_OFF,0,LED_TWINK_FOREVER);
		mwqState.waterFlowState = NO_WATER_FLOW;
        LOG_D("no water erro\n");
//test		return RT_ERROR;
	}


    LOG_D("BEGIN TOC adjust\n");
	LedAct(LED_TOC_MEASURE,LED_OFF,100,10); // 5 sec

    result = WTOC_SendDate((rt_uint8_t *)WQAdjust, sizeof(WQAdjust));
    if (result != RT_EOK)
    {
        LOG_E("result:%d\n", result);
    }

    rt_thread_delay(2000);

	return result;

}

void TOC_Measure_thread_entry(void *parameter)
{
    rt_err_t result;
    rt_uint32_t waterVolumn1,waterVolumn2,sendInfo;
//	struct Msg_ToMain msg;
    rt_uint32_t e;

	rt_thread_delay(500);

	WTT_SelfCheck();

	rt_thread_delay(500);

	sendInfo = 0;

    result = WTOC_SendDate((rt_uint8_t *)WQDevid, sizeof(WQDevid));
    if (result == RT_EOK)
    {
		LedAct(LED_TOC_MEASURE,LED_OFF,6000,1);
	}
	else
	{
		mwqState.tocDevState = STATE_ERRO;
		LedAct(LED_DEV_FAULT,LED_OFF,10000,1);
		LedAct(LED_TOC_ALERT,LED_OFF,10000,1);
	}
	
	if(mwqState.wttDevState == STATE_OK)
	{
		LedAct(LED_WATER_FLOW,LED_OFF,6000,1);
	}
	else
	{
		LedAct(LED_DEV_FAULT,LED_OFF,10000,1);
		LedAct(LED_TDS_ALERT,LED_OFF,10000,1);
	}

    while (1)
    {

	    result = RT_EOK;
	    waterFlowInfo.onMeasure=TOC_NOT_MEASURE;

	    if(sendInfo == 1)
	    {
	    	WIFI_SendMessage(WQ_SEND_INFO);
	    	sendInfo = 0;
    	}
/*	    
		rt_memset(&msg, 0, sizeof(struct Msg_ToMain));
		result = rt_mq_recv(&MQ_ToWQuaThread, &msg, sizeof(struct Msg_ToMain), RT_WAITING_FOREVER);
*/

        /* ��һ�ν����¼����¼� 1 ���¼� 2 ����һ�����Դ����߳� 1�������������¼���־ */
        result = rt_event_recv(&WTocEvent, 
        				(TOC_ADJUST_FLAG | TOC_MEASURE_FLAG | TOC_CHECK_FLAG),
                          RT_EVENT_FLAG_OR | RT_EVENT_FLAG_CLEAR,
                          RT_WAITING_FOREVER, &e) ;
        
  		if (result!= RT_EOK)
        {
        	rt_kprintf("toc msg get error %d \n",result);
            continue;
        }

//        if (msg.MsgType == TOC_MEASURE_FLAG)
        if (e & TOC_MEASURE_FLAG)
        {
        	sendInfo = 1;
			if( mwqState.wttDevState != STATE_OK)
			{
	            rt_kprintf("wttDevState erro\n");
				continue;
			}
			if(mwqState.tocDevState != STATE_OK)
			{
	            rt_kprintf("tocDevState erro\n");
				continue;
			}

			waterFlowInfo.onMeasure=TOC_ON_MEASURE;
			
			LedAct(LED_TOC_MEASURE,LED_ON,0,0); // 5 sec
			
			waterVolumn1 = waterFlowInfo.Pulse_Counter1_local;
            rt_thread_mdelay(2000); //��1.5������������ٸ�λ
            WVV_Ctrl(VALVE_IN_DEV,VALVE_ON);
            rt_thread_mdelay(3000); //ˮ���򿪣�������ˮˮ2����
	        WVV_Ctrl(VALVE_IN_DEV,VALVE_OFF);
            rt_thread_mdelay(4000); //ˮ���رգ��ȶ�2����
            
			LedAct(LED_TOC_MEASURE,LED_OFF,0,0); // 5 sec

			waterVolumn2 = waterFlowInfo.Pulse_Counter1_local;
			if((waterVolumn2 - waterVolumn1)<ONE_SEC_NOWATER_SCOPE * 4)  //��ˮ����û��ˮ����
			{
				LedAct(LED_DEV_FAULT,LED_OFF,7000,1); // 7��
				LedAct(LED_WATER_FLOW,LED_OFF,0,LED_TWINK_FOREVER); // �����ˮ����led�Զ��ָ�
				mwqState.waterFlowState = NO_WATER_FLOW;
	            rt_kprintf("no water erro\n");
//test				continue; //û��ˮ
			}


            rt_kprintf("begin toc check \n");

			LedAct(LED_TOC_MEASURE,LED_OFF,750,LED_TWINK_FOREVER);

            TOC_GetValue();
            
            WVV_Ctrl(VALVE_OUT_DEV,VALVE_ON);
            rt_thread_mdelay(6000); //�Ŵ���ˮ6���� ��ϴtoc������
	        WVV_Ctrl(VALVE_OUT_DEV,VALVE_OFF);
			LedAct(LED_TOC_MEASURE,LED_OFF,0,0);
        }
        
//        else if(msg.MsgType == TOC_ADJUST_FLAG)
        if (e & TOC_ADJUST_FLAG)
        {
			TOC_Adjust();
        }
//        else if(msg.MsgType == TOC_CHECK_FLAG)
        if (e & TOC_CHECK_FLAG)
        {
		    result = WTOC_SendDate((rt_uint8_t *)WQDevid, sizeof(WQDevid));
		    if (result != RT_EOK)
		    {
//		        rt_kprintf("TOC_Self_Check ERRO\n");

				mwqState.tocDevState = STATE_ERRO;
			}
		    else
		    {
				mwqState.tocDevState = STATE_OK;
		    }
        }
 /*      else if(msg.MsgType == WMQ_RESET_FLAG)
         if (e & WMQ_RESET_FLAG)
       {
        	WQ_Reset();
        }
*/
    }

}

int TOC_init(void)
{
    rt_err_t result;
#if 0
    rt_mq_init(&MQ_ToWQuaThread, "zgb_rx_mq",
               MQpool_ToWQuaThread,                   /* �����Ϣ�Ļ����� */
               sizeof(struct Msg_ToMain),      /* һ����Ϣ����󳤶� */
               sizeof(MQpool_ToWQuaThread),           /* �����Ϣ�Ļ�������С */
               RT_IPC_FLAG_FIFO);                /* ����ж���̵߳ȴ������������ȵõ��ķ���������Ϣ */

#endif
				
    result = rt_event_init(&WTocEvent, "event", RT_IPC_FLAG_PRIO);
    if (result != RT_EOK)
    {
        LOG_E("init event failed.\n");
        return -1;
    }
    
    rt_thread_init(&TocMeasure_Thread, "TOC_Measure_Thread", TOC_Measure_thread_entry,
                   RT_NULL, &TocMeasure_thread_stack[0], sizeof(TocMeasure_thread_stack),
                   TOC_THREAD_PRIORITY, TOC_THREAD_TICK);
    rt_thread_startup(&TocMeasure_Thread);


   
   return RT_EOK;

}

void WQ_SelfCheck(void)
{
	static rt_uint8_t devConState = 0;

	TOC_Action(TOC_CHECK_FLAG);
	WTT_SelfCheck();
	

	if((mwqState.tocDevState!=mwqLastState.tocDevState) || (mwqState.waterFlowState!=mwqLastState.waterFlowState)
		|| (mwqState.waterLeakageState!=mwqLastState.waterLeakageState) || (mwqState.wttDevState!=mwqLastState.wttDevState)
		|| (mwqState.tocAlert!=mwqLastState.tocAlert) || 		(mwqState.tdsAlert!=mwqLastState.tdsAlert))
	{
		faultAlertReport = NEET_REPORT;
	}

	mwqLastState.tdsAlert = mwqState.tdsAlert;
	mwqLastState.tocAlert = mwqState.tocAlert;
	mwqLastState.tocDevState = mwqState.tocDevState;
	mwqLastState.wttDevState = mwqState.wttDevState;
	mwqLastState.waterFlowState = mwqState.waterFlowState;


	if(mwqState.tocDevState || mwqState.wttDevState || mwqState.waterFlowState ) 
	{
		devConState = 1;
		LedAct(LED_DEV_FAULT,LED_OFF,7000,1);

		if(mwqState.wttDevState==STATE_ERRO)
		{
			LedAct(LED_TDS_ALERT,LED_OFF,7000,1);
		}
		else
		{
			LedAct(LED_TDS_ALERT,LED_OFF,0,0);
		}

		if(mwqState.tocDevState==STATE_ERRO)
		{
			LedAct(LED_TOC_ALERT,LED_OFF,7000,1);
		}
		else
		{
			LedAct(LED_TOC_ALERT,LED_OFF,0,0);
		}

		if(mwqState.waterFlowState == NO_WATER_FLOW)
		{
			LedAct(LED_WATER_FLOW,LED_OFF,200 ,17);
		}


	}
	else
	{
		if (devConState == 1)
		{
			LedAct(LED_DEV_FAULT,LED_OFF,0,0);
			LedAct(LED_TOC_ALERT,LED_OFF,0,0);
			LedAct(LED_TDS_ALERT,LED_OFF,0,0);
		}
		devConState = 0;

		if(mwqState.waterLeakageState == WATER_LEAKAGE)
		{
			LedAct(LED_DEV_FAULT,LED_OFF,200,17); // 7��
		}

	}

	if(mwqState.tocDevState== STATE_OK)
	{
		if(mwqState.tocAlert == STATE_ERRO)
		{
			LedAct(LED_TOC_ALERT,LED_OFF,200,18);  // 7 sec
		}
		else
		{
			LedAct(LED_TOC_ALERT,LED_OFF,0,0);
		}
	}

	if(mwqState.wttDevState == STATE_OK)
	{
		if(mwqState.tdsAlert == ORIG_TDS_ALERT)
		{
			LedAct(LED_TDS_ALERT,LED_OFF,200,18);
		}
		else
		{
			LedAct(LED_TDS_ALERT,LED_OFF,0,0);
		}
	}

	if(mwqState.tdsAlert == PURE_TDS_ALERT) //��߱���
	{
		LedAct(LED_TDS_ALERT,LED_OFF,200,18);
		LedAct(LED_DEV_FAULT,LED_OFF,200,18);
		LedAct(LED_TOC_ALERT,LED_OFF,200,18);
	}

	
	
}

void WQ_Reset(void)
{
	int i;
	// ����
	for(i=0;i<LED_MAX_NUMB;i++)
		LedAct(i,LED_ON,300,10);

	//��������������ݣ����flash��¼�
	waterFlowInfo.localVolumn = 0;
//	FLASH_WriteWaterVolum(0);

		rt_thread_delay(5000);

	for(i=0;i<LED_MAX_NUMB;i++)
		LedAct(i,LED_OFF,0,0);


}



//INIT_APP_EXPORT(wq_thread_init);

